package com.yc.io.niodemo;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;

/**
 * Channel的基础示例
 * @author samuelchen
 * @version 1.0
 * @date 2022-03-25
 */
public class BasicChannelDemo {

    public static void main(String[] args) throws Exception
    {
        BasicChannelDemo basicChannelDemo = new BasicChannelDemo();
//        basicChannelDemo.testFileChannel();

        basicChannelDemo.testFileInputStream();

    }

    /**
     * 普通流对文件读取操作，获取文件内容
     * @author samuelchen
     * @date 2022/3/25
     * @param
     * @throws IOException
     */
    public void testFileInputStream() throws IOException {
//            FileInputStream fileInputStream
//                    = new FileInputStream("/Users/samuelchen/desktop/channel.txt"); // 文件流
//            InputStreamReader isr
//                    = new InputStreamReader(fileInputStream);//字符流
//            BufferedReader br
//                    = new BufferedReader(isr); //缓冲
            BufferedReader brffer = new BufferedReader(new InputStreamReader(new FileInputStream("/Users/samuelchen/desktop/channel.txt")));
            String line = null;
            while( (line=brffer.readLine())!=null ){//字符不等于空
                System.out.println(line);//一行一行地du输出
            }
            brffer.close();//关闭文件
    }


    /**
     * FileChannel 读取文件内容，包含中文
     * @author samuelchen
     * @date 2022/3/25
     * @throws IOException
     */
    public void testFileChannel() throws IOException {
        // 解决中文乱码
        Charset charset = Charset.forName("utf-8");
        CharsetDecoder charsetDecoder = charset.newDecoder();

        // 打开文件通道
        RandomAccessFile randomAccessFile = new RandomAccessFile("/Users/samuelchen/desktop/channel.txt", "rw");
        FileChannel channel = randomAccessFile.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(32);

        CharBuffer cb = CharBuffer.allocate(512);

        int bytesRead = channel.read(buffer); // 从文件通道读取字节到buffer.
        char[] tmp = null; // 临时存放转码后的字符
        byte[] remainByte = null;// 存放decode操作后未处理完的字节。decode仅仅转码尽可能多的字节，此次转码不了的字节需要缓存，下次再转
        int leftNum = 0; // 未转码的字节数


        int read = channel.read(buffer);
        while (read != -1) {
//            System.out.println("Read" + read);
            buffer.flip();
            // 处理中文乱码
            charsetDecoder.decode(buffer, cb, false);
            cb.flip();
            // ===

            remainByte = null;
            leftNum = buffer.limit() - buffer.position();
            if (leftNum > 0) { // 记录未转换完的字节
                remainByte = new byte[leftNum];
                buffer.get(remainByte, 0, leftNum);
            }

            // 输出已转换的字符
//            tmp = new char[cb.length()];
//            while (cb.hasRemaining()) {
//                cb.get(tmp);
//                System.out.print(new String(tmp));
//            }

            while (cb.hasRemaining()) {
                System.out.println(cb.get());
            }
            buffer.clear();
            cb.clear();

            if (remainByte != null) {
                buffer.put(remainByte); // 将未转换完的字节写入bBuf，与下次读取的byte一起转换
            }
            read = channel.read(buffer);
        }
        randomAccessFile.close();

    }
}
